<?php
/**
 * php GEM Project
 * 
 * LICENSE
 * 
 * PHP System Architecture Enabling Rapid Application Deployment and Scalability
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @copyright Copyright (C) 2010 Zeletron LLC (http://zeletron.com)
 * @license http://gem.zeletron.com/license
 */

/*
 * GEM/Model/Domain/Image.php
 * 
 * This class extends GEM_Model_Domain_File to
 * include functionality specific to images.
 * 
 * This class uses the Fileinfo library, standard with PHP 5.3. 
 * 
 * @author David Joly
 * @link http://zeletron.com
 * 
 * @category GEM
 * @package GEM_Model
 * @subpackage GEM_Model_Domain
 */
class GEM_Model_Domain_Image extends GEM_Model_Domain_File
{
	/**
	 * Resized Image
	 * 
	 * @var image resource
	 */
	protected $_resized;
	
	/**
	 * Returns the image url. If the image is located in a public
	 * directory, the url will point to the file. If the image
	 * is located in a private directory, the url will point to
	 * the FileController's image action.
	 * 
	 * Overloads parent class getUrl() method.
	 * @see GEM_Model_Domain_File#getUrl()
	 * 
	 * By default, the fully qualified url will be returned.
	 * Also by default, the width and height options will be
	 * set to zero (0). The FileController's image action
	 * will display the full image as a result.
	 * 
	 * $options = array(
	 * 		'fullyQualified' => true,
	 * 		'width'	=> 0,
	 * 		'height' => 0
	 * 	)
	 * 
	 * @param array $options
	 * @return string
	 */
	public function getUrl(array $options = array())
	{
		$fullyQualified = array_key_exists('fullyQualified',$options) ? $options['fullyQualified'] : true;
		$url = $fullyQualified ? Zend_Registry::get('config')->base_url : '';
		if($this->isPublic()){
			$url .= substr($this->getPath(true),strlen(PUBLIC_PATH));
		} else {
			$height = array_key_exists('height',$options) ? (int)$options['height'] : 0;
			$width = array_key_exists('width',$options) ? (int)$options['width'] : 0;
			$url .= "/image/$width/$height/{$this->_id}/{$this->_basename}";
		}
		return $url;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/GEM/Model/Domain/GEM_Model_Domain_File#clearFile()
	 */
	public function clearFile()
	{
		$this->_resized = null;
		parent::clearFile();
	}
	
	/**
	 * Outputs the image file
	 * 
	 * @param int $width optional
	 * @param int $height optional
	 * @return void
	 */
	public function render($width = 0, $height = 0)
	{
		$image = ($width > 0 || $height > 0) ? $this->createResized($width,$height) : $this->create();;
		switch($this->_mimeType){
			case 'image/png':
				imagepng($image);	
			break;
			case 'image/gif':
				imagegif($image);
			break;
			case 'image/wbmp': 
				imagewbmp($image);
			break;
			default: 
				imagejpeg($image); 
			break;
		}
	}
	
	/**
	 * Returns a resized image of the original
	 * within the specified width and height.
	 * 
	 * @param int $width
	 * @param int $height
	 * @return image resource
	 */
	public function createResized($width,$height)
	{
		return $this->_resizeImage($width,$height);
		if(is_null($this->_resized)){
			$this->_resized = $this->_resizeImage($width,$height);
		} elseif(imagesx($this->_resized) != $width || imagesy($this->_resized) != $height){
			$this->_resized = $this->_resizeImage($width,$height);
		}
		return $this->_resized;
	}
	
	/**
	 * Returns the original image.
	 * 
	 * @return image resource
	 */
	public function create()
	{
		if(is_null($this->_file)) $this->_makeImage();
		return $this->_file;
	}
	
	/**
	 * Resizes the image to within the specified
	 * height and width.

	 * @param int $width
	 * @param int $height
	 * @return image resource
	 */
	protected function _resizeImage($width, $height)
	{
		if(is_null($this->_file)) $this->_makeImage();
		$image = $this->_file; //Original image
		$originalWidth = imagesx($image); //150
		$originalHeight = imagesy($image);//250
		
		if($height == 0 && $width > 0){
			$height = $width; 
		}
		if($width == 0 && $height > 0){
			$width = $height; 
		};
		
		
		if($originalWidth > $width || $originalHeight > $height){		
	    	if($originalWidth > $width){
				$resizedWidth = $width; //100
				$widthRatio = $resizedWidth/$originalWidth; // 100/150 = 0.66 
				$resizedHeight = $originalHeight*$widthRatio; // 250*0.66 = 165
				if($resizedHeight > $height){
					$heightRatio = $height/$resizedHeight; // 100/165 = 0.60
					$resizedHeight = $height; //100
					$resizedWidth = $resizedWidth*$heightRatio; // 100*0.60 = 60
				}
	    	} elseif ($originalHeight > $height){
	    		$resizedHeight = $height;
				$heightRatio = $resizedHeight/$originalHeight;
				$resizedWidth = $originalWidth*$heightRatio;
	    		if($resizedWidth > $width){
					$widthRatio = $width/$resizedWidth;
					$resizedWidth = $width;
					$resizedHeight = $resizedHeight*$widthRatio; 
				}
	    	}
	    	$resized = imagecreatetruecolor($resizedWidth, $resizedHeight);		
			//Copy original image to thumbnail image
			imagecopyresampled($resized, $image,0,0,0,0, $resizedWidth,$resizedHeight,$originalWidth,$originalHeight);   	
	    	return $resized;
		}
		return $image;			
	}
	
	/**
	 * Create an image depending on the set mime type
	 * and saves it to the _file property of the parent
	 * class.
	 *  
	 * @return void
	 */
	protected function _makeImage()
	{
		$image = null;
		$path = $this->getPath(true);
		
		switch($this->getMimeType()){
			case 'image/png' : 
				$image = @imagecreatefrompng($path);
				break;
			case 'image/gif' :
				$image = @imagecreatefromgif($path);
				break;
			case 'image/wbmp' :
				$image = @imagecreatefromwbmp($path);
				break;
			case 'image/jpeg' :
			case 'image/jpg' : 
				$image = @imagecreatefromjpeg($path);
				break;
			default :
				throw new GEM_Model_Domain_Exception("{$this->getMimeType} is not a valid image mime type.");	
				break;	
		}
		if(is_resource($image)){
			$this->_file = $image;
		} else {
			throw new GEM_Model_Domain_Exception("Failed to create image.");
		}
	}
}